

<!DOCTYPE html>
<html class="writer-html5" lang="en" >
<head>
  <meta charset="utf-8" />
  
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  
  <title>Mantle &mdash; Ceph Documentation</title>
  

  
  <link rel="stylesheet" href="../../_static/ceph.css" type="text/css" />
  <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
  <link rel="stylesheet" href="../../_static/graphviz.css" type="text/css" />
  <link rel="stylesheet" href="../../_static/css/custom.css" type="text/css" />

  
  
    <link rel="shortcut icon" href="../../_static/favicon.ico"/>
  

  
  

  

  
  <!--[if lt IE 9]>
    <script src="../../_static/js/html5shiv.min.js"></script>
  <![endif]-->
  
    
      <script type="text/javascript" id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
        <script src="../../_static/jquery.js"></script>
        <script src="../../_static/underscore.js"></script>
        <script src="../../_static/doctools.js"></script>
    
    <script type="text/javascript" src="../../_static/js/theme.js"></script>

    
    <link rel="index" title="Index" href="../../genindex/" />
    <link rel="search" title="Search" href="../../search/" />
    <link rel="next" title="实验性功能" href="../experimental-features/" />
    <link rel="prev" title="LibCephFS (Python 接口)" href="../api/libcephfs-py/" /> 
</head>

<body class="wy-body-for-nav">

   
  <header class="top-bar">
    

















<div role="navigation" aria-label="breadcrumbs navigation">

  <ul class="wy-breadcrumbs">
    
      <li><a href="../../" class="icon icon-home"></a> &raquo;</li>
        
          <li><a href="../">Ceph 文件系统</a> &raquo;</li>
        
      <li>Mantle</li>
    
    
      <li class="wy-breadcrumbs-aside">
        
          
            <a href="../../_sources/cephfs/mantle.rst.txt" rel="nofollow"> View page source</a>
          
        
      </li>
    
  </ul>

  
  <hr/>
</div>
  </header>
  <div class="wy-grid-for-nav">
    
    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
      <div class="wy-side-scroll">
        <div class="wy-side-nav-search"  style="background: #eee" >
          

          
            <a href="../../">
          

          
            
            <img src="../../_static/logo.png" class="logo" alt="Logo"/>
          
          </a>

          

          
<div role="search">
  <form id="rtd-search-form" class="wy-form" action="../../search/" method="get">
    <input type="text" name="q" placeholder="Search docs" />
    <input type="hidden" name="check_keywords" value="yes" />
    <input type="hidden" name="area" value="default" />
  </form>
</div>

          
        </div>

        
        <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
          
            
            
              
            
            
              <ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../../start/intro/">Ceph 简介</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../install/">安装 Ceph</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../cephadm/">Cephadm</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../rados/">Ceph 存储集群</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="../">Ceph 文件系统</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="../#cephfs">CephFS 入门</a></li>
<li class="toctree-l2"><a class="reference internal" href="../#id4">管理</a></li>
<li class="toctree-l2"><a class="reference internal" href="../#id5">挂载 CephFS</a></li>
<li class="toctree-l2"><a class="reference internal" href="../#id6">CephFS 内幕</a></li>
<li class="toctree-l2 current"><a class="reference internal" href="../#id7">故障排除和灾难恢复</a><ul class="current">
<li class="toctree-l3"><a class="reference internal" href="../eviction/"> 驱逐客户端</a></li>
<li class="toctree-l3"><a class="reference internal" href="../scrub/"> 洗刷</a></li>
<li class="toctree-l3"><a class="reference internal" href="../full/"> 文件系统占满的处理</a></li>
<li class="toctree-l3"><a class="reference internal" href="../disaster-recovery-experts/"> 元数据修复</a></li>
<li class="toctree-l3"><a class="reference internal" href="../troubleshooting/"> 故障排除</a></li>
<li class="toctree-l3"><a class="reference internal" href="../disaster-recovery/"> 灾难恢复</a></li>
<li class="toctree-l3"><a class="reference internal" href="../cephfs-journal-tool/"> cephfs-journal-tool</a></li>
<li class="toctree-l3"><a class="reference internal" href="../recover-fs-after-mon-store-loss/"> 监视器存储丢失后恢复文件系统</a></li>
<li class="toctree-l3 current"><a class="reference internal" href="../#id8">开发者指南</a><ul class="current">
<li class="toctree-l4"><a class="reference internal" href="../journaler/"> Journaler 配置</a></li>
<li class="toctree-l4"><a class="reference internal" href="../capabilities/"> 客户端的能力</a></li>
<li class="toctree-l4"><a class="reference internal" href="../api/"> Java 和 Python 捆绑库</a></li>
<li class="toctree-l4 current"><a class="current reference internal" href="#"> Mantle</a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../#id9">更多细节</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../rbd/">Ceph 块设备</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../radosgw/">Ceph 对象网关</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../mgr/">Ceph 管理器守护进程</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../mgr/dashboard/">Ceph 仪表盘</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../api/">API 文档</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../architecture/">体系结构</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../dev/developer_guide/">开发者指南</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../dev/internals/">Ceph 内幕</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../governance/">项目管理</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../foundation/">Ceph 基金会</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../ceph-volume/">ceph-volume</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../releases/general/">Ceph 版本（总目录）</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../releases/">Ceph 版本（索引）</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../security/">Security</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../glossary/">Ceph 术语</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../jaegertracing/">Tracing</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../translation_cn/">中文版翻译资源</a></li>
</ul>

            
          
        </div>
        
      </div>
    </nav>

    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">

      
      <nav class="wy-nav-top" aria-label="top navigation">
        
          <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
          <a href="../../">Ceph</a>
        
      </nav>


      <div class="wy-nav-content">
        
        <div class="rst-content">
        
          <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
           <div itemprop="articleBody">
            
<div id="dev-warning" class="admonition note">
  <p class="first admonition-title">Notice</p>
  <p class="last">This document is for a development version of Ceph.</p>
</div>
  <div id="docubetter" align="right" style="padding: 5px; font-weight: bold;">
    <a href="https://pad.ceph.com/p/Report_Documentation_Bugs">Report a Documentation Bug</a>
  </div>

  
  <div class="section" id="mantle">
<h1>Mantle<a class="headerlink" href="#mantle" title="Permalink to this headline">¶</a></h1>
<div class="admonition warning">
<p class="admonition-title">Warning</p>
<p>Mantle 的本意是用于研究和开发元数据均衡算法，不是给 CephFS
生产集群用的。</p>
</div>
<p>Multiple, active MDSs can migrate directories to balance metadata load. The
policies for when, where, and how much to migrate are hard-coded into the
metadata balancing module. Mantle is a programmable metadata balancer built
into the MDS. The idea is to protect the mechanisms for balancing load
(migration, replication, fragmentation) but stub out the balancing policies
using Lua. Mantle is based on [1] but the current implementation does <em>NOT</em>
have the following features from that paper:</p>
<ol class="arabic simple">
<li><p>Balancing API: in the paper, the user fills in when, where, how much, and
load calculation policies; currently, Mantle only requires that Lua policies
return a table of target loads (e.g., how much load to send to each MDS)</p></li>
<li><p>“How much” hook: in the paper, there was a hook that let the user control
the fragment selector policy; currently, Mantle does not have this hook</p></li>
<li><p>Instantaneous CPU utilization as a metric</p></li>
</ol>
<p>[1] Supercomputing ‘15 Paper:
<a class="reference external" href="http://sc15.supercomputing.org/schedule/event_detail-evid=pap168.html">http://sc15.supercomputing.org/schedule/event_detail-evid=pap168.html</a></p>
<div class="section" id="vstart">
<h2>vstart 快速入门<a class="headerlink" href="#vstart" title="Permalink to this headline">¶</a></h2>
<div class="admonition warning">
<p class="admonition-title">Warning</p>
<p>Developing balancers with vstart is difficult because running all daemons
and clients on one node can overload the system. Let it run for a while, even
though you will likely see a bunch of lost heartbeat and laggy MDS warnings.
Most of the time this guide will work but sometimes all MDSs lock up and you
cannot actually see them spill. It is much better to run this on a cluster.</p>
</div>
<p>As a prerequisite, we assume you have installed <a class="reference external" href="https://sourceforge.net/projects/mdtest/">mdtest</a> or pulled the <a class="reference external" href="https://hub.docker.com/r/michaelsevilla/mdtest/">Docker image</a>. We use mdtest because we
need to generate enough load to get over the MIN_OFFLOAD threshold that is
arbitrarily set in the balancer. For example, this does not create enough
metadata load:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">while</span> <span class="n">true</span><span class="p">;</span> <span class="n">do</span>
  <span class="n">touch</span> <span class="s2">&quot;/cephfs/blah-`date`&quot;</span>
<span class="n">done</span>
</pre></div>
</div>
<div class="section" id="mantle-with-vstart-sh">
<h3>Mantle with <cite>vstart.sh</cite><a class="headerlink" href="#mantle-with-vstart-sh" title="Permalink to this headline">¶</a></h3>
<ol class="arabic simple">
<li><p>Start Ceph and tune the logging so we can see migrations happen:</p></li>
</ol>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>cd build
../src/vstart.sh -n -l
for i in a b c; do
  bin/ceph --admin-daemon out/mds.$i.asok config set debug_ms 0
  bin/ceph --admin-daemon out/mds.$i.asok config set debug_mds 2
  bin/ceph --admin-daemon out/mds.$i.asok config set mds_beacon_grace 1500
done
</pre></div>
</div>
<ol class="arabic simple" start="2">
<li><p>Put the balancer into RADOS:</p></li>
</ol>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">bin</span><span class="o">/</span><span class="n">rados</span> <span class="n">put</span> <span class="o">--</span><span class="n">pool</span><span class="o">=</span><span class="n">cephfs_metadata_a</span> <span class="n">greedyspill</span><span class="o">.</span><span class="n">lua</span> <span class="o">../</span><span class="n">src</span><span class="o">/</span><span class="n">mds</span><span class="o">/</span><span class="n">balancers</span><span class="o">/</span><span class="n">greedyspill</span><span class="o">.</span><span class="n">lua</span>
</pre></div>
</div>
<ol class="arabic simple" start="3">
<li><p>Activate Mantle:</p></li>
</ol>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">bin</span><span class="o">/</span><span class="n">ceph</span> <span class="n">fs</span> <span class="nb">set</span> <span class="n">cephfs</span> <span class="n">max_mds</span> <span class="mi">5</span>
<span class="nb">bin</span><span class="o">/</span><span class="n">ceph</span> <span class="n">fs</span> <span class="nb">set</span> <span class="n">cephfs_a</span> <span class="n">balancer</span> <span class="n">greedyspill</span><span class="o">.</span><span class="n">lua</span>
</pre></div>
</div>
<ol class="arabic simple" start="4">
<li><p>Mount CephFS in another window:</p></li>
</ol>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>  <span class="nb">bin</span><span class="o">/</span><span class="n">ceph</span><span class="o">-</span><span class="n">fuse</span> <span class="o">/</span><span class="n">cephfs</span> <span class="o">-</span><span class="n">o</span> <span class="n">allow_other</span> <span class="o">&amp;</span>
  <span class="n">tail</span> <span class="o">-</span><span class="n">f</span> <span class="n">out</span><span class="o">/</span><span class="n">mds</span><span class="o">.</span><span class="n">a</span><span class="o">.</span><span class="n">log</span>


<span class="n">Note</span> <span class="n">that</span> <span class="k">if</span> <span class="n">you</span> <span class="n">look</span> <span class="n">at</span> <span class="n">the</span> <span class="n">last</span> <span class="n">MDS</span> <span class="p">(</span><span class="n">which</span> <span class="n">could</span> <span class="n">be</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="ow">or</span> <span class="n">c</span> <span class="o">--</span> <span class="n">it</span><span class="s1">&#39;s</span>
<span class="n">random</span><span class="p">),</span> <span class="n">you</span> <span class="n">will</span> <span class="n">see</span> <span class="n">an</span> <span class="n">an</span> <span class="n">attempt</span> <span class="n">to</span> <span class="n">index</span> <span class="n">a</span> <span class="n">nil</span> <span class="n">value</span><span class="o">.</span> <span class="n">This</span> <span class="ow">is</span> <span class="n">because</span> <span class="n">the</span>
<span class="n">last</span> <span class="n">MDS</span> <span class="n">tries</span> <span class="n">to</span> <span class="n">check</span> <span class="n">the</span> <span class="n">load</span> <span class="n">of</span> <span class="n">its</span> <span class="n">neighbor</span><span class="p">,</span> <span class="n">which</span> <span class="n">does</span> <span class="ow">not</span> <span class="n">exist</span><span class="o">.</span>
</pre></div>
</div>
<ol class="arabic simple" start="5">
<li><p>Run a simple benchmark. In our case, we use the Docker mdtest image to
create load:</p></li>
</ol>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>for i in 0 1 2; do
  docker run -d \
    --name=client$i \
    -v /cephfs:/cephfs \
    michaelsevilla/mdtest \
    -F -C -n 100000 -d &quot;/cephfs/client-test$i&quot;
done
</pre></div>
</div>
<ol class="arabic simple" start="6">
<li><p>When you’re done, you can kill all the clients with:</p></li>
</ol>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>for i in 0 1 2 3; do docker rm -f client$i; done
</pre></div>
</div>
</div>
<div class="section" id="id1">
<h3>输出解析<a class="headerlink" href="#id1" title="Permalink to this headline">¶</a></h3>
<p>Looking at the log for the first MDS (could be a, b, or c), we see that
everyone has no load:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>2016-08-21 06:44:01.763930 7fd03aaf7700  0 lua.balancer MDS0: &lt; auth.meta_load=0.0 all.meta_load=0.0 req_rate=1.0 queue_len=0.0 cpu_load_avg=1.35 &gt; load=0.0
2016-08-21 06:44:01.763966 7fd03aaf7700  0 lua.balancer MDS1: &lt; auth.meta_load=0.0 all.meta_load=0.0 req_rate=0.0 queue_len=0.0 cpu_load_avg=1.35 &gt; load=0.0
2016-08-21 06:44:01.763982 7fd03aaf7700  0 lua.balancer MDS2: &lt; auth.meta_load=0.0 all.meta_load=0.0 req_rate=0.0 queue_len=0.0 cpu_load_avg=1.35 &gt; load=0.0
2016-08-21 06:44:01.764010 7fd03aaf7700  2 lua.balancer when: not migrating! my_load=0.0 hisload=0.0
2016-08-21 06:44:01.764033 7fd03aaf7700  2 mds.0.bal  mantle decided that new targets={}
</pre></div>
</div>
<p>After the jobs starts, MDS0 gets about 1953 units of load. The greedy spill
balancer dictates that half the load goes to your neighbor MDS, so we see that
Mantle tries to send 1953 load units to MDS1.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>2016-08-21 06:45:21.869994 7fd03aaf7700  0 lua.balancer MDS0: &lt; auth.meta_load=5834.188908912 all.meta_load=1953.3492228857 req_rate=12591.0 queue_len=1075.0 cpu_load_avg=3.05 &gt; load=1953.3492228857
2016-08-21 06:45:21.870017 7fd03aaf7700  0 lua.balancer MDS1: &lt; auth.meta_load=0.0 all.meta_load=0.0 req_rate=0.0 queue_len=0.0 cpu_load_avg=3.05 &gt; load=0.0
2016-08-21 06:45:21.870027 7fd03aaf7700  0 lua.balancer MDS2: &lt; auth.meta_load=0.0 all.meta_load=0.0 req_rate=0.0 queue_len=0.0 cpu_load_avg=3.05 &gt; load=0.0
2016-08-21 06:45:21.870034 7fd03aaf7700  2 lua.balancer when: migrating! my_load=1953.3492228857 hisload=0.0
2016-08-21 06:45:21.870050 7fd03aaf7700  2 mds.0.bal  mantle decided that new targets={0=0,1=976.675,2=0}
2016-08-21 06:45:21.870094 7fd03aaf7700  0 mds.0.bal    - exporting [0,0.52287 1.04574] 1030.88 to mds.1 [dir 100000006ab /client-test2/ [2,head] auth pv=33 v=32 cv=32/0 ap=2+3+4 state=1610612802|complete f(v0 m2016-08-21 06:44:20.366935 1=0+1) n(v2 rc2016-08-21 06:44:30.946816 3790=3788+2) hs=1+0,ss=0+0 dirty=1 | child=1 dirty=1 authpin=1 0x55d2762fd690]
2016-08-21 06:45:21.870151 7fd03aaf7700  0 mds.0.migrator nicely exporting to mds.1 [dir 100000006ab /client-test2/ [2,head] auth pv=33 v=32 cv=32/0 ap=2+3+4 state=1610612802|complete f(v0 m2016-08-21 06:44:20.366935 1=0+1) n(v2 rc2016-08-21 06:44:30.946816 3790=3788+2) hs=1+0,ss=0+0 dirty=1 | child=1 dirty=1 authpin=1 0x55d2762fd690]
</pre></div>
</div>
<p>Eventually load moves around:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>2016-08-21 06:47:10.210253 7fd03aaf7700  0 lua.balancer MDS0: &lt; auth.meta_load=415.77414300449 all.meta_load=415.79000078186 req_rate=82813.0 queue_len=0.0 cpu_load_avg=11.97 &gt; load=415.79000078186
2016-08-21 06:47:10.210277 7fd03aaf7700  0 lua.balancer MDS1: &lt; auth.meta_load=228.72023977691 all.meta_load=186.5606496623 req_rate=28580.0 queue_len=0.0 cpu_load_avg=11.97 &gt; load=186.5606496623
2016-08-21 06:47:10.210290 7fd03aaf7700  0 lua.balancer MDS2: &lt; auth.meta_load=0.0 all.meta_load=0.0 req_rate=1.0 queue_len=0.0 cpu_load_avg=11.97 &gt; load=0.0
2016-08-21 06:47:10.210298 7fd03aaf7700  2 lua.balancer when: not migrating! my_load=415.79000078186 hisload=186.5606496623
2016-08-21 06:47:10.210311 7fd03aaf7700  2 mds.0.bal  mantle decided that new targets={}
</pre></div>
</div>
</div>
</div>
<div class="section" id="id2">
<h2>实现细节<a class="headerlink" href="#id2" title="Permalink to this headline">¶</a></h2>
<p>Most of the implementation is in MDBalancer. Metrics are passed to the balancer
policies via the Lua stack and a list of loads is returned back to MDBalancer.
It sits alongside the current balancer implementation and it’s enabled with a
Ceph CLI command (“ceph fs set cephfs balancer mybalancer.lua”). If the Lua policy
fails (for whatever reason), we fall back to the original metadata load
balancer. The balancer is stored in the RADOS metadata pool and a string in the
MDSMap tells the MDSs which balancer to use.</p>
<div class="section" id="exposing-metrics-to-lua">
<h3>Exposing Metrics to Lua<a class="headerlink" href="#exposing-metrics-to-lua" title="Permalink to this headline">¶</a></h3>
<p>Metrics are exposed directly to the Lua code as global variables instead of
using a well-defined function signature. There is a global “mds” table, where
each index is an MDS number (e.g., 0) and each value is a dictionary of metrics
and values. The Lua code can grab metrics using something like this:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">mds</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="s2">&quot;queue_len&quot;</span><span class="p">]</span>
</pre></div>
</div>
<p>This is in contrast to cls-lua in the OSDs, which has well-defined arguments
(e.g., input/output bufferlists). Exposing the metrics directly makes it easier
to add new metrics without having to change the API on the Lua side; we want
the API to grow and shrink as we explore which metrics matter. The downside of
this approach is that the person programming Lua balancer policies has to look
at the Ceph source code to see which metrics are exposed. We figure that the
Mantle developer will be in touch with MDS internals anyways.</p>
<p>The metrics exposed to the Lua policy are the same ones that are already stored
in mds_load_t: auth.meta_load(), all.meta_load(), req_rate, queue_length,
cpu_load_avg.</p>
</div>
<div class="section" id="id3">
<h3>编译、执行均衡器<a class="headerlink" href="#id3" title="Permalink to this headline">¶</a></h3>
<p>Here we use <cite>lua_pcall</cite> instead of <cite>lua_call</cite> because we want to handle errors
in the MDBalancer. We do not want the error propagating up the call chain. The
cls_lua class wants to handle the error itself because it must fail gracefully.
For Mantle, we don’t care if a Lua error crashes our balancer – in that case,
we’ll fall back to the original balancer.</p>
<p>The performance improvement of using <cite>lua_call</cite> over <cite>lua_pcall</cite> would not be
leveraged here because the balancer is invoked every 10 seconds by default.</p>
</div>
<div class="section" id="returning-policy-decision-to-c">
<h3>Returning Policy Decision to C++<a class="headerlink" href="#returning-policy-decision-to-c" title="Permalink to this headline">¶</a></h3>
<p>We force the Lua policy engine to return a table of values, corresponding to
the amount of load to send to each MDS. These loads are inserted directly into
the MDBalancer “my_targets” vector. We do not allow the MDS to return a table
of MDSs and metrics because we want the decision to be completely made on the
Lua side.</p>
<p>Iterating through tables returned by Lua is done through the stack. In Lua
jargon: a dummy value is pushed onto the stack and the next iterator replaces
the top of the stack with a (k, v) pair. After reading each value, pop that
value but keep the key for the next call to <cite>lua_next</cite>.</p>
</div>
<div class="section" id="reading-from-rados">
<h3>Reading from RADOS<a class="headerlink" href="#reading-from-rados" title="Permalink to this headline">¶</a></h3>
<p>All MDSs will read balancing code from RADOS when the balancer version changes
in the MDS Map. The balancer pulls the Lua code from RADOS synchronously. We do
this with a timeout: if the asynchronous read does not come back within half
the balancing tick interval the operation is cancelled and a Connection Timeout
error is returned. By default, the balancing tick interval is 10 seconds, so
Mantle will use a 5 second second timeout. This design allows Mantle to
immediately return an error if anything RADOS-related goes wrong.</p>
<p>We use this implementation because we do not want to do a blocking OSD read
from inside the global MDS lock. Doing so would bring down the MDS cluster if
any of the OSDs are not responsive – this is tested in the ceph-qa-suite by
setting all OSDs to down/out and making sure the MDS cluster stays active.</p>
<p>One approach would be to asynchronously fire the read when handling the MDS Map
and fill in the Lua code in the background. We cannot do this because the MDS
does not support daemon-local fallbacks and the balancer assumes that all MDSs
come to the same decision at the same time (e.g., importers, exporters, etc.).</p>
</div>
<div class="section" id="id4">
<h3>调试<a class="headerlink" href="#id4" title="Permalink to this headline">¶</a></h3>
<p>Logging in a Lua policy will appear in the MDS log. The syntax is the same as
the cls logging interface:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">BAL_LOG</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="s2">&quot;this is a log message&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>It is implemented by passing a function that wraps the <cite>dout</cite> logging framework
(<cite>dout_wrapper</cite>) to Lua with the <cite>lua_register()</cite> primitive. The Lua code is
actually calling the <cite>dout</cite> function in C++.</p>
<p>Warning and Info messages are centralized using the clog/Beacon. Successful
messages are only sent on version changes by the first MDS to avoid spamming
the <cite>ceph -w</cite> utility. These messages are used for the integration tests.</p>
</div>
<div class="section" id="id5">
<h3>测试<a class="headerlink" href="#id5" title="Permalink to this headline">¶</a></h3>
<p>Testing is done with the ceph-qa-suite (tasks.cephfs.test_mantle). We do not
test invalid balancer logging and loading the actual Lua VM.</p>
</div>
</div>
</div>



           </div>
           
          </div>
          <footer>
    <div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
        <a href="../experimental-features/" class="btn btn-neutral float-right" title="实验性功能" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
        <a href="../api/libcephfs-py/" class="btn btn-neutral float-left" title="LibCephFS (Python 接口)" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
    </div>

  <hr/>

  <div role="contentinfo">
    <p>
        &#169; Copyright 2016, Ceph authors and contributors. Licensed under Creative Commons Attribution Share Alike 3.0 (CC-BY-SA-3.0).

    </p>
  </div> 

</footer>
        </div>
      </div>

    </section>

  </div>
  

  <script type="text/javascript">
      jQuery(function () {
          SphinxRtdTheme.Navigation.enable(true);
      });
  </script>

  
  
    
   

</body>
</html>